﻿#pragma once

#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string>
#include <tchar.h>
#include "../Render/VulkanRHI.h"

#include "PlatTypeUtil.h"

#define RENDER_DOC 0

class LogUtils
{
	static uint32 sTlsSlot;

	TCHAR szBuffer[2048];
	TCHAR szB2[2048];
	SYSTEMTIME st;

#if RENDER_DOC
	std::ofstream outfile;
#endif

public:

	static LogUtils& Get();

	LogUtils();

	virtual ~LogUtils();

	void LogFormat(const char* file, const char* func, int line, const TCHAR* szFormat, ...);
};

#define LOG_DEBUG

#define __FILENAME__ (strrchr(__FILE__, '\\') + 1) // Windows下文件目录层级是'\\'

#ifdef LOG_DEBUG

#define LOGV(fmt, ...) LogUtils::Get().LogFormat(__FILENAME__, __FUNCTION__, __LINE__, "VERBOSE : " fmt, ##__VA_ARGS__);
#define LOGI(fmt, ...) LogUtils::Get().LogFormat(__FILENAME__, __FUNCTION__, __LINE__, "INFO : " fmt, ##__VA_ARGS__);
#define LOGW(fmt, ...) LogUtils::Get().LogFormat(__FILENAME__, __FUNCTION__, __LINE__, "WARNING : " fmt, ##__VA_ARGS__);
#define LOGE(fmt, ...) LogUtils::Get().LogFormat(__FILENAME__, __FUNCTION__, __LINE__, "ERROR : " fmt, ##__VA_ARGS__);

#else
#define LOGV(fmt, ...);
#define LOGD(fmt, ...);
#define LOGI(fmt, ...);
#define LOGW(fmt, ...);
#define LOGE(fmt, ...);
#endif

namespace MGUtils
{
	std::wstring ErrStr(VkResult errorCode);
}

#define VK_CHECK_RESULT(f)																				\
{																										\
	VkResult res = (f);																					\
	if (res != VK_SUCCESS)																				\
	{																									\
		LOGE(L"VkResult is \" %s \"", MGUtils::ErrStr(res).c_str());                                    \
		assert(res == VK_SUCCESS);																		\
	}																									\
}

#define VK_PROCESS() LOGI(L"VKP %s", UTF8_TO_TCHAR(__FUNCTION__))
